using System;
using Microsoft.SPOT;
using Gadgeteer.Interfaces.Timed;

namespace Gadgeteer.Interfaces.GT
{
    public class TimerFactory : TimerFactoryBase, ITimerFactory
    {
        public override ITimer Create(TimeSpan dueIn, TimeSpan interval, TimerBehavior behavior)
        {
            if (dueIn.Milliseconds != interval.Milliseconds)
                throw new NotSupportedException("Delays are not supported in NET.MF Timer, might be added by combining 2 timers later on (1: due by RunOnce timer, 2: create from 1.Tick");

            var timer =  new TimerWrapper(
               new Timer(interval, behavior.Convert())
               );
            return timer;
        }

        private class TimerWrapper : ITimer
        {
            private readonly Timer timer;

            public TimerWrapper(Timer timer)
            {
                this.timer = timer;
                timer.Tick += OnTick;
            }

            private void OnTick(Timer timer)
            {
                var ev = Tick;
                if (ev != null)
                    ev(this);
            }

            public event TickEventHandler Tick;

            public TimerBehavior Behavior
            {
                get { throw new NotImplementedException(); }
            }

            public TimeSpan Interval
            {
                get
                {
                    throw new NotImplementedException();
                }
                set
                {
                    throw new NotImplementedException();
                }
            }

            public bool IsRunning
            {
                get { return timer.IsRunning; }
            }

            public void Restart()
            {
                timer.Restart();
            }

            public void Start()
            {
                timer.Start();
            }

            public void Stop()
            {
                timer.Stop();
            }
        }
    }

    public static class TimerBehaviorConversion
    {
        public static TimerBehavior Convert(this Timer.BehaviorType value)
        {
            switch (value)
            {
                case Timer.BehaviorType.RunContinuously:
                    return TimerBehavior.RunContinuously;
                case Timer.BehaviorType.RunOnce:
                    return TimerBehavior.RunOnce;
                default:
                    throw new NotSupportedException("Unkown type " + value);
            }
        }

        public static Timer.BehaviorType Convert(this TimerBehavior value)
        {
            switch (value)
            {
                case TimerBehavior.RunContinuously:
                    return Timer.BehaviorType.RunContinuously;
                case TimerBehavior.RunOnce:
                    return Timer.BehaviorType.RunOnce;
                default:
                    throw new NotSupportedException("Unkown type " + value);
            }
        }
    }
}
